import urllib, urllib2, re, xbmcplugin, xbmcgui, xbmcaddon, os
from urllib import urlopen
from time import strftime
from BeautifulSoup import BeautifulSoup, BeautifulStoneSoup
from xml.etree import ElementTree as ET

__settings__ = xbmcaddon.Addon(id='plugin.video.britishtech-dev')
__language__ = __settings__.getLocalizedString


## TODO:
## Add debug check
## parse xml file from URL :DONE
## change live stream to parse details from URL :DONE
## clean code
## change images back to thumbnails :DONE
## add live show not on air message
## add google analytics tracking code
## change jtv to use param to genericaize (sic?) it :DONE
## rework JTV swf code :DONE
## add twit stream option for debugging :DONE

AUDIOSHOWS_URL="http://www.britishtechnetwork.com/wsinfo.php?btnuser=xbmc&btnpwd=cjpcvxbmc&reqfor=xbmc&medtype=audio&format=xml"
VIDEOSHOWS_URL="http://www.britishtechnetwork.com/wsinfo.php?btnuser=xbmc&btnpwd=cjpcvxbmc&reqfor=xbmc&medtype=video&format=xml"
LIVEVIDEO_URL="http://www.britishtechnetwork.com/wsinfo.php?btnuser=xbmc&btnpwd=cjpcvxbmc&reqfor=xbmc&medtype=livevideo&format=xml"

def addon_log(string):
##        if debug == 'true':
##            xbmc.log("[addon.BTN-%s]: %s" %(addon_version, string))
            xbmc.log("[addon.BTN]: %s" %(string))

def make_request(url):
        try:
            headers = {'User-agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0',
                       'Referer' : 'http://www.britishtechnetwork.com'}
            req = urllib2.Request(url,None,headers)
            response = urllib2.urlopen(req)
            data = response.read()
            response.close()
            return data
        except urllib2.URLError, e:
            addon_log( 'We failed to open "%s".' % url)
            if hasattr(e, 'reason'):
                addon_log('We failed to reach a server.')
                addon_log('Reason: ', e.reason)
            if hasattr(e, 'code'):
                addon_log('We failed with error code - %s.' % e.code)

def get_params():
        param=[]
        paramstring=sys.argv[2]
        if len(paramstring)>=2:
            params=sys.argv[2]
            cleanedparams=params.replace('?','')
            if (params[len(params)-1]=='/'):
                params=params[0:len(params)-2]
            pairsofparams=cleanedparams.split('&')
            param={}
            for i in range(len(pairsofparams)):
                splitparams={}
                splitparams=pairsofparams[i].split('=')
                if (len(splitparams))==2:
                    param[splitparams[0]]=splitparams[1]
        return param

def BUILDVIDEOSHOWS(append='') :
##    Stub as expecting more settings here later, for now will call a generic fuction
    BUILDSHOWS(VIDEOSHOWS_URL, append)

def BUILDAUDIOSHOWS(append='') :
##    Stub as expecting more settings here later,for now will call a generic fuction
    BUILDSHOWS(AUDIOSHOWS_URL, append)

def BUILDSHOWS(URL, append='') :
    shows = {}
    tree = ET.parse(urlopen(URL))
    root = tree.getroot()

    for show in root.findall('category'):
        name = show.find('name').text
        name = name + append

        # hack!
        name = name.replace(" - video","")
        feed = show.find('feed').text
        image = show.find('thumbnail').text
##        fan art to be used later
##        image = show.find('fanart').text
        plot = show.find('description').text
        genre = 'Technology'
        shows[name] = {
            'feed': feed,
            'image': image,
            'plot': plot,
            'genre': genre,
        }

    # Loop through each of the shows and add them as directories.
    x = 2

    # This setting disabled by default
    #quality = int(__settings__.getSetting("video_quality"))
    for name, data in shows.iteritems():
        # @TODO Get the ordering correct.
        data['count'] = x
        x = x + 1
        addDir(name, data['feed'], 1, data['image'], data)


def BUILDLIVEVIDEO(append='',showstring='britishtechlive'):
    # British Tech Network Live Stream via Justin TV
    tree = ET.parse(urlopen(LIVEVIDEO_URL))
    root = tree.getroot()

    for show in root.findall('category'):
        name = show.find('name').text
        name = name + append
        feed = show.find('feed').text
        image = show.find('thumbnail').text
##        will use fanart later
##        image = show.find('fanart').text
        plot = show.find('description').text
        genre = 'Technology'

    addLink(
        name = name,
        url = get_jtv(showstring),
        date = '',
        iconimage = image,
        info = {
            'title': name,
            'plot': plot,
            'genre': genre,
            'count': 1
        }
    )

def getSwfUrl(channel_name):
        """Helper method to grab the swf url, resolving HTTP 301/302 along the way"""
        base_url = 'http://www.justin.tv/widgets/live_embed_player.swf?channel=%s' % channel_name
        headers = {'User-agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0',
                   'Referer' : 'http://www.justin.tv/'+channel_name}
        req = urllib2.Request(base_url, None, headers)
        response = urllib2.urlopen(req)
        return response.geturl()

def get_jtv(showstring):
    try:
        link = 'http://usher.justin.tv/find/' + showstring + '.xml?type=live'
        soup = BeautifulSoup(make_request(link))
        token = ' jtv='+soup.token.string.replace('\\','\\5c').replace(' ','\\20').replace('"','\\22')
        rtmp = soup.connect.string+'/'+soup.play.string
        Pageurl = ' Pageurl=http://www.justin.tv/' + showstring
        swf_url = getSwfUrl(showstring)
        swf = ' swfUrl=%s swfVfy=1 live=1' % swf_url
        url = rtmp+token+swf+Pageurl
##        addon_log('Stream: %s' %url)
        return url
    except:
        return ''

def INDEX(name, url, page):
    # Load the XML feed.
    data = urllib2.urlopen(url)

    # Parse the data with BeautifulStoneSoup, noting any self-closing tags.
    soup = BeautifulStoneSoup(data, convertEntities=BeautifulStoneSoup.XML_ENTITIES, selfClosingTags=['media:thumbnail', 'enclosure', 'media:content'])
    count = 1

    # Figure out where to start and where to stop the pagination.
    # TODO: Fix the Episodes per Page setting.
    episodesperpage = int(float(__settings__.getSetting("episodes_per_page")))
    start = episodesperpage * int(page);
    print "Episodes per Page: " + str(episodesperpage) + "\n"
    print "Start:" + str(start);
    n = 0;

    # Wrap in a try/catch to protect from broken RSS feeds.
    try:
        for item in soup.findAll('item'):
            # Set up the pagination properly.
            n += 1
            if (n < start):
                # Skip this episode since it's before the page starts.
                continue
            if (n >= start + episodesperpage):
                # Add a go to next page link, and skip the rest of the loop.
                addDir(
                    name = __language__(30300),
                    url = url,
                    mode= 1,
                    iconimage = os.path.join(__settings__.getAddonInfo('path'), 'resources', 'media', 'next.png'),
                    info = {},
                    page = page + 1
                )
                break

            # Load up the initial episode information.
            info = {}
            title = item.find('title')
            info['title'] = str(n) + '. '
            if (title):
                info['title'] += title.string
            info['tvshowtitle'] = name
            info['count'] = count
            count += 1 # Increment the show count.

            # Get the video enclosure.
            video = ''
            enclosure = item.find('enclosure')
            if (enclosure != None):
                video = enclosure.get('href')
                if (video == None):
                    video = enclosure.get('url')
                if (video == None):
                    video = ''
                size = enclosure.get('length')
                if (size != None):
                    info['size'] = int(size)

            # TODO: Parse the date correctly.
            date = ''
            pubdate = item.find('pubDate')
            if (pubdate != None):
                date = pubdate.string
                # strftime("%d.%m.%Y", item.updated_parsed)

            # Plot outline.
            summary = item.find('itunes:summary')
            if (summary != None):
                info['plot'] = info['plotoutline'] = summary.string.strip()

            # Plot.
            description = item.find('description')
            if (description != None):
                # Attempt to strip the HTML tags.
                try:
                    info['plot'] = re.sub(r'<[^>]*?>', '', description.string)
                except:
                    info['plot'] = description.string

            # Author/Director.
            author = item.find('itunes:author')
            if (author != None):
                info['director'] = author.string

            # Load the self-closing media:thumbnail data.
            thumbnail = ''
            mediathumbnail = item.findAll('media:thumbnail')
            if (mediathumbnail):
                thumbnail = mediathumbnail[0]['url']

            # Add the episode link.
            addLink(info['title'], video, date, thumbnail, info)
    except:
       pass
    xbmcplugin.setContent(int( sys.argv[1] ), 'episodes')
    xbmcplugin.endOfDirectory(int(sys.argv[1]))

def get_params():
        param=[]
        paramstring=sys.argv[2]
        if len(paramstring)>=2:
                params=sys.argv[2]
                cleanedparams=params.replace('?','')
                if (params[len(params)-1]=='/'):
                        params=params[0:len(params)-2]
                pairsofparams=cleanedparams.split('&')
                param={}
                for i in range(len(pairsofparams)):
                        splitparams={}
                        splitparams=pairsofparams[i].split('=')
                        if (len(splitparams))==2:
                                param[splitparams[0]]=splitparams[1]

        return param

# Info takes Plot, date, size
def addLink(name, url, date, iconimage, info):
        liz = xbmcgui.ListItem(name, date, iconImage=iconimage, thumbnailImage=iconimage)
        liz.setProperty('IsPlayable', 'true')
        liz.setInfo(type="Video", infoLabels = info)
        return xbmcplugin.addDirectoryItem(
            handle = int(sys.argv[1]),
            url = url,
            listitem = liz,
            isFolder = False
        )

def addDir(name, url, mode, iconimage, info, page = 0):
    u=sys.argv[0]+"?url="+urllib.quote_plus(url)+"&mode="+str(mode)+"&name="+urllib.quote_plus(name) + "&page="+str(page)
    ok=True
    info["Title"] = name
    liz=xbmcgui.ListItem(name, iconImage=iconimage, thumbnailImage=iconimage)
    liz.setInfo(type="video", infoLabels=info)
    ok=xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=liz,isFolder=True)
    return ok


# Begin main

params = get_params()
url = None
name = None
mode = None
page = None

try:
        url = urllib.unquote_plus(params["url"])
except:
        pass
try:
        name = urllib.unquote_plus(params["name"])
except:
        pass
try:
        mode = int(params["mode"])
except:
        pass
try:
        page = int(params["page"])
except:
        page = 0

print "Mode: "+str(mode)
print "URL: "+str(url)
print "Name: "+str(name)
print "Page: "+str(page)


## Create intitial listing
if mode==None or url==None or len(url)<1:
    params=get_params()
    try :
        content_type = params['content_type']
    except :
        content_type = 'all'

#### Not happy with this, can't change listings when started with shortcut!
    if content_type == 'video' :
        addon_log(content_type)
        BUILDLIVEVIDEO()
        BUILDLIVEVIDEO(' - [TWiT for testing]', 'twit')
        BUILDLIVEVIDEO(' - [Random for testing]', 'roll24productions')
        BUILDVIDEOSHOWS()
    elif content_type == 'audio' :
        addon_log(content_type)
        BUILDAUDIOSHOWS()
    else :
        addon_log(content_type)
        BUILDLIVEVIDEO()
        BUILDLIVEVIDEO(' - [TWiT for testing]', 'twit')
        BUILDLIVEVIDEO(' - [Random for testing]', 'roll24productions')
        BUILDVIDEOSHOWS(" - [Video]")
        BUILDAUDIOSHOWS(" - [Audio]")

elif mode==1:
        INDEX(name, url, page)

xbmcplugin.endOfDirectory(int(sys.argv[1]))
